package cn.mandy.sysadmin.controller;

import cn.mandy.sysadmin.common.api.CommonResult;
import cn.mandy.sysadmin.common.api.MmPage;
import cn.mandy.sysadmin.component.AuthenticationUser;
import cn.mandy.sysadmin.constant.MandyConstant;
import cn.mandy.sysadmin.dto.*;
import cn.mandy.sysadmin.model.*;
import cn.mandy.sysadmin.service.MandyCacheService;
import cn.mandy.sysadmin.service.MandyRbacService;
import cn.mandy.sysadmin.service.MandyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 后台用户管理
 * Created by macro on 2018/4/26.
 */
@Controller
@Api(tags = "MandySysadminController", description = "后台用户管理")
@RequestMapping("/sysadmin")
public class MandySysadminController {
    @Autowired
    private AuthenticationUser authenticationMmUser;

    @Autowired
    private MandyRbacService mandyRbacService;

    @Autowired
    private MandyService mandyService;

    @Autowired
    private MandyCacheService mandyCacheService;

    @Value("${jwt.tokenHeader}")
    private String tokenHeader;
    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @ApiOperation(value = "登录以后返回token")
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult login(@RequestBody @Validated MandyLoginParam umsAdminLoginParam, BindingResult result) {
        String token = mandyRbacService.login(umsAdminLoginParam.getUsername(), umsAdminLoginParam.getPassword());
        if (token == null) {
            return CommonResult.validateFailed("用户名或密码错误");
        }
        Map<String, String> tokenMap = new HashMap<>();
        tokenMap.put("token", token);
        tokenMap.put("tokenHead", tokenHead);
        return CommonResult.success(tokenMap);
    }

    @ApiOperation(value = "登出功能")
    @RequestMapping(value = "/logout", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult logout(@RequestBody MandLogout mandLogout) {
        //当newRoleId 大于0时才切换当前角色
        Long newRoleId = mandLogout.getNewRoleId();
        if (null != newRoleId && newRoleId.compareTo(0L) > 0){
            mandyRbacService.changeCurrentRoleId(newRoleId);
        }
        return CommonResult.success("登出成功");
    }

    @ApiOperation(value = "刷新token")
    @RequestMapping(value = "/token/refresh", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult refreshToken(HttpServletRequest request) {
        String token = request.getHeader(tokenHeader);
        String refreshToken = mandyRbacService.refreshToken(token);
        if (refreshToken == null) {
            return CommonResult.failed();
        }
        Map<String, String> tokenMap = new HashMap<>();
        tokenMap.put("token", refreshToken);
        tokenMap.put("tokenHead", tokenHead);
        return CommonResult.success(tokenMap);
    }

    //返回当前用户的基本信息, 菜单, 权限
    @ApiOperation(value = "获取当前登录用户信息")
    @RequestMapping(value = "/info", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult getUserInfo() {
        MandyUserDetail user = authenticationMmUser.getCurrentMmUser();
        List<MandyMainMenu> mainMenu = new ArrayList<>();
        List<Long> roles = new ArrayList<>();
        //审核通过且用户使用状态正常情况下, 才返回该用户当前角色的菜单
        if (!MandyConstant.AuditState.UNCHECKED.equals(user.getMandyUser().getAuditState())
            && MandyConstant.UserState.NORMAL.equals(user.getMandyUser().getUserState())){
            mainMenu = mandyCacheService.getRoleMainMenu(user.getMandyUser().getCurrentRoleId());
        }

        Map<String, Object> data = new HashMap<>();
        //user.getMandyUser().setPassword(null);
        data.put("user", user);
        data.put("menu", mainMenu);
        Long blobDataId = user.getMandyUser().getAvatar();
        data.put("avatar", mandyRbacService.getAvatar(blobDataId));
        return CommonResult.success(data);
    }

    @ApiOperation("面板功能-面板列表")
    @RequestMapping(value = "/panel/list", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<List<MandyPermission>> panelList(MandyPanelListParam panelListParam) {
        List<MandyPermission> panels = mandyService.panelList(panelListParam);
        return  CommonResult.success(panels);
    }

    @ApiOperation("面板功能-面板复制")
    @RequestMapping(value = "/panel/copy", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<MandyPermission> panelCopy(@RequestBody MandyPermission panel) {
        mandyService.panelCopy(panel);
        return CommonResult.success(panel);
    }

    @ApiOperation("面板功能-修改面板")
    @RequestMapping(value = "/panel/update", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<MandyPermission> panelUpdate(@RequestBody MandyPermission panel) {
        int ret = mandyService.panelUpdate(panel);
        if (ret == 1){
           return CommonResult.success(panel);
        }

        return CommonResult.failed("不满足更新条件, 不允许操作！");
    }

    @ApiOperation("面板功能-复核面板")
    @RequestMapping(value = "/panel/audit", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<MandyPermission> panelAudit(@RequestBody MandyPermission panel) {
        mandyService.panelAudit(panel);
        return CommonResult.success(panel);
    }

    @ApiOperation("数据字典--返回所有字典数据")
    @RequestMapping(value = "/dict/list", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<List<MandyDictFrontEnd>> dictList() {
        List<MandyDictFrontEnd> ret = mandyCacheService.dictList();
        return  CommonResult.success(ret);
    }

    @ApiOperation("角色管理-角色列表")
    @RequestMapping(value = "/role/list", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<List<MandyRole>> roleList() {
        List<MandyRole> roles = mandyService.roleList();
        return  CommonResult.success(roles);
    }

    @ApiOperation("角色管理-复制角色")
    @RequestMapping(value = "/role/copy", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<MandyRole> roleCopy(@RequestBody MandyRole sysMmRole) {
        int ret = mandyService.roleCopy(sysMmRole);
        if (ret == 1) {
            return CommonResult.success(sysMmRole);
        }
        return CommonResult.failed("不满足更新条件, 不允许操作！");
    }

    //反例
    //不建议使用PathVariable, 对权限判断造成不必要的麻烦, 还是统一都用RequestBody好
    @ApiOperation("角色管理-角色详情-返回菜单及参数等详细信息,用于修改")
    @RequestMapping(value = "/role/detail/{roleId}", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<MandyRoleDetail> roleDetail(@PathVariable Long roleId) {
        return  CommonResult.success(mandyService.getRoleMenuForUpdate(roleId));
    }

    @ApiOperation("角色管理-修改角色-审核后才正式生效")
    @RequestMapping(value = "/role/update", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<MandyRole> roleUpdate(@RequestBody List<MandyRoleResource> mandyRoleResources) {
        MandyRole ret = mandyService.roleUpdate(mandyRoleResources);
        if (ret == null) {
            return CommonResult.failed();
        }
        return CommonResult.success(ret);
    }


    @ApiOperation("角色管理-菜单组列表")
    @RequestMapping(value = "/role/listMenuGroup", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<List<MandyPermission>> listMenuGroup() {
        List<MandyPermission> menuGroups = mandyService.listAllMenuGroups();
        return  CommonResult.success(menuGroups);
    }

    @ApiOperation("角色管理-新增菜单组")
    @RequestMapping(value = "/role/createMenuGroup", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<MandyRoleMenuGroup> createMenuGroup(@RequestBody MandyRoleMenuGroup sysMmRoleMenuGroup) {
        //mandyService.menuGroupCreate(sysMmRoleMenuGroup);
        return CommonResult.success(mandyService.createMenuGroup(sysMmRoleMenuGroup));
    }

    @ApiOperation("角色管理-面板列表(通过复核)-作为备选项供选择")
    @RequestMapping(value = "/role/listPanel", method = RequestMethod.GET)
    @ResponseBody
    //审核通过状态的面板才能使用.
    public CommonResult<List<MandyPermission>> roleListPanel() {
        List<MandyPermission> panels = mandyService.listAllAuditedPanels();
        return  CommonResult.success(panels);
    }

    @ApiOperation("角色管理-参数列表-")
    @RequestMapping(value = "/role/listParameter", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<List<MandyParameter>> roleListParameter(){
        return CommonResult.success(mandyService.getAllParameters());
    }

    @ApiOperation("角色管理-启用角色")
    @RequestMapping(value = "/role/enable", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<MandyRole> roleEnable(@RequestBody MandyRole sysMmRole) {
        MandyRole ret = mandyService.roleEnable(sysMmRole);
        if (ret == null) {
            return CommonResult.failed();
        }
        return CommonResult.success(ret);
    }

    @ApiOperation("角色管理-禁用角色")
    @RequestMapping(value = "/role/disable", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<MandyRole> roleDisable(@RequestBody MandyRole sysMmRole) {
        MandyRole ret = mandyService.roleDisable(sysMmRole);
        if (ret == null) {
            return CommonResult.failed();
        }
        return CommonResult.success(ret);
    }

    //分页的处理
    @ApiOperation("用户管理-用户列表, 只有pageStart 等于0时才执行总数查询")
    @RequestMapping(value = "/user/list", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<MmPage> userList(@RequestBody MandyUserWithRolesParam sysMmUserWithRolesParam) {
        MandyUserDetail userDetail =  authenticationMmUser.getCurrentMmUser();
        //获取参数值
        List<MandyParameter> parameters = userDetail.getParameters();
        for (MandyParameter parameter: parameters) {
            //参数处理
            if ("dept_rang".equals(parameter.getName())){
                if (MandyConstant.DeptRang.ALL.equals(parameter.getDefaultValue())){
                    sysMmUserWithRolesParam.setDepartmentEqual(null);
                    sysMmUserWithRolesParam.setDepartmentLike(null);
                } else if (MandyConstant.DeptRang.USER_DEPT.equals(parameter.getDefaultValue())){
                    sysMmUserWithRolesParam.setDepartmentEqual(userDetail.getMandyUser().getDepartmentId());
                    sysMmUserWithRolesParam.setDepartmentLike(null);
                } else if (MandyConstant.DeptRang.USER_DEPT_EXT.equals(parameter.getDefaultValue())){
                    sysMmUserWithRolesParam.setDepartmentEqual(null);
                    sysMmUserWithRolesParam.setDepartmentLike(userDetail.getMandyUser().getDepartmentPath());
                }
            }
        }

        Long total = -1L;
        MmPage mmPage = new MmPage();
        if (sysMmUserWithRolesParam.getPageStart().equals(0L)){
            total = mandyService.countUser(sysMmUserWithRolesParam);
            if (total.equals(0L)){
                return  CommonResult.success(mmPage);
            }
        }
        List<MandyUserWithRoles> userList = mandyService.listUser(sysMmUserWithRolesParam);
        mmPage.setResultSet(userList);
        mmPage.setTotal(total);
        return  CommonResult.success(mmPage);
    }

    @ApiOperation("用户管理-创建用户")
    @RequestMapping(value = "/user/create", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<MandyUserCreateParam> userCreate(@RequestBody MandyUserCreateParam sysMmUserCreateParam) {
        MandyUserCreateParam ret;
        ret =  mandyService.userCreate(sysMmUserCreateParam);
        return  CommonResult.success(ret);
    }

    @ApiOperation("用户管理-部门列表")
    @RequestMapping(value = "/user/listDepartment", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<List<MandyDepartment>> userListDepartment() {
        List<MandyDepartment> deps = mandyService.listDepartment();
        return  CommonResult.success(deps);
    }

    @ApiOperation("用户管理-设置离职")
    @RequestMapping(value = "/user/disable", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<MandyUserWithRoles> userDisable(@RequestBody MandyUserWithRoles sysMmUserWithRoles) {
        MandyUserWithRoles ret;
        ret =  mandyService.userDisable(sysMmUserWithRoles);
        return  CommonResult.success(ret);
    }

    @ApiOperation("用户管理-设置在职")
    @RequestMapping(value = "/user/enable", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<MandyUserWithRoles> userEnable(@RequestBody MandyUserWithRoles sysMmUserWithRoles) {
        MandyUserWithRoles ret;
        ret =  mandyService.userEnable(sysMmUserWithRoles);
        return  CommonResult.success(ret);
    }

    @ApiOperation("用户管理-部门调整")
    @RequestMapping(value = "/user/newDepartment", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<MandyUserWithRoles> userNewDepartment(@RequestBody MandyUserWithRoles sysMmUserWithRoles) {
        MandyUserWithRoles ret;
        ret =  mandyService.userNewDepartment(sysMmUserWithRoles);
        return  CommonResult.success(ret);
    }

    @ApiOperation("用户管理-审计复核")
    @RequestMapping(value = "/user/audit", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<MandyUserWithRoles> userAudit(@RequestBody MandyUserWithRoles sysMmUserWithRoles) {
        MandyUserWithRoles ret;
        ret =  mandyService.userAudit(sysMmUserWithRoles);
        return  CommonResult.success(ret);
    }

    //API 粒度问题, 同样或者类似的功能(与/role/list比较), 使用场景不一样,
    //这里是在调整用户角色的时候, 可供选择的角色列表, 候选角色的范围
    @ApiOperation("用户管理-角色列表")
    @RequestMapping(value = "/user/listRole", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<List<MandyRole>> userListRole() {
        List<MandyRole> roles = mandyService.roleList();
        return  CommonResult.success(roles);
    }

    @ApiOperation("用户管理-角色调整")
    @RequestMapping(value = "/user/newRole", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<MandyUserWithRoles> userRolesAdjust(@RequestBody MandyUserWithRoles sysMmUserWithRoles) {
        MandyUserWithRoles ret;
        ret =  mandyService.userNewRoles(sysMmUserWithRoles);
        if (ret != null) {
            return CommonResult.success(ret);
        }

        return CommonResult.failed("系统内部错误, 后台库里不存在该用户信息！");
    }


    //TODO 密码重置, 用户更新自己的密码后需要再次复核
    @ApiOperation("用户管理-用户密码重置")
    @RequestMapping(value = "/user/passwordReset", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<MandyUserWithRoles> userPasswordReset(@RequestBody MandyUserWithRoles sysMmUserWithRoles) {
        MandyUserWithRoles ret;
        ret =  mandyService.userPasswordReset(sysMmUserWithRoles);
        if (ret != null) {
            return CommonResult.success(ret);
        }
        return CommonResult.failed("系统内部错误！");
    }

    @ApiOperation("用户注册")
    @RequestMapping(value = "/register", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<Integer> register(@RequestBody MandyRegister mandyRegister) {
        int ret =  mandyRbacService.register(mandyRegister);
        if (ret == 0) {
            return CommonResult.success(ret);
        }
        return CommonResult.failed("系统内部错误！");
    }

    @ApiOperation("密码修改")
    @RequestMapping(value = "/password", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<Integer> passwordUpdate(@RequestBody MandyUser mandyUser) {
        int ret = mandyRbacService.passwordUpdate(mandyUser);
        if (ret == 0) {
            return CommonResult.success(ret);
        }
        return CommonResult.failed("系统内部错误！");
    }

}
